/*
 * Licensed to the 南京汇海交通科技有限公司
 *
 * Copyright (c) 2025.
 * All rights reserved.
 *
 * 本软件属南京汇海交通科技有限公司所有，在未获得南京汇海交通科技有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.chframework.boot.web.exception.handler;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;
import com.chframework.boot.core.response.result.ApiResult;
import com.chframework.boot.core.response.status.ApiStatusEnum;
import com.chframework.boot.core.support.ApiHelper;
import com.chframework.common.exception.SystemInterrupterException;
import com.chframework.common.exception.SystemMessageException;
import com.chframework.common.extend.ExceptionHelper;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.StringJoiner;

@Slf4j
class ExceptionConverter {

    /**
     * 全局异常处理程序
     */
    static ApiResult<Object> convert(Exception exception) {
        String errJson = ExceptionHelper.getMessage(exception);
        List<Class<?>> causeList = ExceptionHelper.getCauseList(exception);

        ApiResult<Object> apiResult;
        if (causeList.contains(SystemMessageException.class)) { // 因业务校验不通过而手动抛出的异常 - JSON报文
            if (JSONUtil.isTypeJSONObject(errJson)) {
                apiResult = JSONUtil.toBean(errJson, new TypeReference<ApiResult<Object>>() {
                }, false);
                log.error(apiResult.getMessage(), exception);
            } else {
                apiResult = ApiResult.build().setStatus(ApiStatusEnum.ERR_B0001);
                log.error(errJson, exception);
            }
        } else if (causeList.contains(SystemInterrupterException.class)) { // 因业务校验不通过而手动抛出的异常 - 业务校验不通过的状态码
            StringJoiner joiner = new StringJoiner("");
            apiResult = ApiHelper.buildResult(errJson, joiner);
            log.error(joiner.toString(), exception);
        } else { // 未被捕获 或者 已经捕获在重新包装后 而抛出的运行时异常
            apiResult = ApiResult.build().setStatus(ApiStatusEnum.ERR_B0001);
            log.error(errJson, exception);
        }

        // 将异常响应结果返回
        return apiResult;
    }

}
